package org.example.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.example.anno.PreAuth;
import org.example.model.LoginUser;
import org.example.utils.Opt;
import org.example.utils.Opts;
import org.example.utils.RequestUtils;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;

@Aspect
@Component
@EnableAspectJAutoProxy
@Slf4j
public class PreAuthAspectHandler {

    // @PreAuth 注解
    @Pointcut("@annotation(org.example.anno.PreAuth)")
    public void pointcut() {
        // Pointcut definition
    }


    @Before("pointcut()")
    public void before(JoinPoint joinPoint) {
        // 获取方法入参 和获取方法上的注解
        // 判断用户是否有权限
        // 如果没有权限，抛出异常
        // 如果有权限，继续执行方法
        // 获取方法名
        Object[] args = joinPoint.getArgs();
        MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
        // 获取注解
        PreAuth preAuth = methodSignature.getMethod().getAnnotation(PreAuth.class);
        String value = Opt.of(preAuth.value()).orElse("");
        if(value.isEmpty()){
            // 获取请求对象 request
            log.error("没有权限配置,跳过权限校验,url：{}", RequestUtils.getCurrentRequest().getRequestURI() );
            return ;
        }
        boolean judge = false;
        for (Object arg : args) {
            Opt<Object> argOpt = Opt.of(arg);
            if(argOpt.isPresent() && argOpt.get() instanceof LoginUser) {
                LoginUser loginUser = (LoginUser)argOpt.get();
                judge = true;
                if(!hasPermission(loginUser, preAuth)) {

                    throw new RuntimeException("没有权限");
                }
            }
        }
        if(!judge){
            Object loginUser = RequestUtils.getCurrentRequest().getAttribute("LoginUser");
            if(loginUser instanceof LoginUser) {
                LoginUser user = (LoginUser)loginUser;
                if(!hasPermission(user, preAuth)) {
                    log.error("没有权限1,url：{}", RequestUtils.getCurrentRequest().getRequestURI() );
                    throw new RuntimeException("没有权限");
                }
            }else {
                log.error("没有权限2,url：{}", RequestUtils.getCurrentRequest().getRequestURI() );
                throw new RuntimeException("没有权限");
            }
        }

    }

    private boolean hasPermission(LoginUser loginUser, PreAuth preAuth) {
        String value = preAuth.value();
        List<String> permissions = loginUser.getPermissions();
        Optional<String> authOpt = Opts.of(permissions).filter(permission -> permission.equals(value)).first();

        if(authOpt.isPresent()){
            log.info("用户有权限,用户id:{}，权限:{},注解配置:{}", loginUser.getUsername(), permissions, value);
            return true;
        }
        log.error("用户没有权限,用户id:{}，权限:{},注解配置:{}", loginUser.getUsername(), permissions, value);
        return false;
    }
}
